//
//
//
//
// Queue.C
//

#include "Queue.h"
#include "BaseQueueMsg.h"
#include "Exception.h"


Queue::Queue(U32 max) : _max(max){};

Queue::~Queue(){};

BaseQueueMsg* Queue::Front()
{
	while(_msgList.size() == 0)
	{}

	MutexVal val(_mutex);
	BaseQueueMsg* p = _msgList.front();
	_msgList.pop_front();
	return p;
}

//
//
// push message to list front
//
U32 Queue::Front(BaseQueueMsg* msg)
{
	if(NULL == msg)
		throw Exception("NULL input msg found");

	// with no priority, just directly put at front
	while(_msgList.size() >= _max)
	{}

	MutexVal val(_mutex);
	_msgList.push_front(msg);
	return _msgList.size();
}

BaseQueueMsg* Queue::Back()
{
	while(_msgList.size() == 0)
	{}

	MutexVal val(_mutex);
	BaseQueueMsg* p = _msgList.back();
	_msgList.pop_back();
	return p;
}

U32 Queue::Back(BaseQueueMsg* msg)
{
	if(NULL == msg)
		throw Exception("NULL msg found when Queue::Back");

	while(_msgList.size() >= _max)
	{}

	MutexVal val(_mutex);
	_msgList.push_back(msg);
	return _msgList.size();
}

U32 Queue::Enqueue(BaseQueueMsg* msg)
{
	while(_msgList.size() >= _max)
	{}

	MutexVal val(_mutex);

	if(0 == _msgList.size())
	{
		_msgList.push_front(msg);
		return _msgList.size();
	}

	if(1 == _msgList.size())
	{
		BaseQueueMsg* f = _msgList.front();
		if(msg->Priority() >= f->Priority())
			_msgList.push_front(msg);
		if(msg->Priority() < f->Priority())
			_msgList.push_back(msg);
		return _msgList.size();
	}

	//_msgList.size() > 1
	//
	BaseQueueMsg* f = _msgList.front();
	BaseQueueMsg* b = _msgList.back();
	if(msg->Priority() >= f->Priority())
	{
		_msgList.push_front(msg);
		return _msgList.size();
	}

	if(msg->Priority() <= b->Priority())
	{
		_msgList.push_back(msg);
		return _msgList.size();
	}

	for(std::list<BaseQueueMsg*>::iterator it = _msgList.begin();
			it != _msgList.end(); it++)
	{
		if((*it)->Priority() <= msg->Priority())
		{
			_msgList.insert(it, msg);
			break;
		}
	}
	return _msgList.size();
}


U32 Queue::Size()
{
	 return _msgList.size();
}
